package mylab.base.model.dto;


import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import mylab.base.enums.HttpCode;

@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel("通用响应")
public class Result<T> extends DTO {

    public static final int SUCCESS = 0;
    public static final int FAILD = 1;
    /**
     * 返回码
     */
    @ApiModelProperty(value = "响应代码", notes = "0:成功,非0:失败")
    private int rc;
    /**
     * 正确时的返回结果
     */
    @ApiModelProperty(value = "响应数据，泛型")
    private T ret;
    /**
     * 失败时的异常信息
     */
    @ApiModelProperty(value = "错误信息，如果 rc 非0")
    private String err;

    private Result(int rc, String err) {
        this(rc, null, err);
    }

    private Result(int rc, T ret) {
        this(rc, ret, null);
    }

    private Result(int rc, T ret, String err) {
        setRc(rc);
        setRet(ret);
        setErr(err);
    }

    public static boolean isSuccess(Result<?> result) {
        return result.getRc() == SUCCESS;
    }


    public static <T> Result<T> newFaild(HttpCode httpCode) {
        return newFaild(httpCode.getValue(), httpCode.getLabel());
    }

    public static <T> Result<T> newFaild(HttpCode httpCode, String message) {
        return newFaild(httpCode.getValue(), message);
    }

    public static <T> Result<T> newResult(HttpCode httpCode, T t) {
        if (httpCode.equals(HttpCode.OK_200)) {
            return newSuccess(t);
        } else {
            return newResult(httpCode.getValue(), t, httpCode.getLabel());
        }
    }

    public static <T> Result<T> newFaild() {
        return newResult(FAILD, null, null);
    }

    public static <T> Result<T> newFaild(String err) {
        return newResult(FAILD, null, err);
    }

    public static <T> Result<T> newFaild(int rc, String err) {
        return newResult(rc, null, err);
    }

    public static <T> Result<T> newSuccess() {
        return newResult(SUCCESS, null, null);
    }

    public static <T> Result<T> newSuccess(T t) {
        return newResult(SUCCESS, t, null);
    }

    private static <T> Result<T> newResult(int rc, T t, String err) {
        return new Result<T>(rc, t, err);
    }

}